package com.ytjj.quartz.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.kuaidi100.sdk.response.PrintBaseResp;
import com.kuaidi100.sdk.response.QueryTrackData;
import com.ytjj.common.api.CommonResult;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.utils.HttpClientUtil;
import com.ytjj.qmyx.mall.model.ExpressOrders;
import com.ytjj.qmyx.mall.model.ReturnRegister;
import com.ytjj.qmyx.users.client.AdminClient;
import com.ytjj.quartz.config.SupplyApiConfig;
import com.ytjj.quartz.dao.ReturnGoodsDao;
import com.ytjj.quartz.model.OrdersInfo;
import com.ytjj.quartz.model.ReturnOrdersResponse;
import com.ytjj.quartz.service.OrdersService;
import com.ytjj.quartz.service.ReturnGoodsOtherService;
import com.ytjj.quartz.service.ReturnGoodsService;
import com.ytjj.quartz.service.ReturnInvalidResponse;
import com.ytjj.quartz.utils.DingDingWebHookUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 * 
 * @Version: 1.0
 */
@Component
@Slf4j
@RefreshScope
public class ReturnGoodsTask {

	@Resource
	private ReturnGoodsService returnGoodsService;
	@Autowired
	private OrdersService ordersService;
	@Resource
	private ReturnGoodsDao returnGoodsDao;
	@Resource
	private AdminClient adminClient;
	@Resource
	private SupplyApiConfig supplyApiConfig;
	@Resource
	private ReturnGoodsOtherService returnGoodsOtherService;

	@Value("${autoReturnMoney:false}")
	private Boolean autoReturnMoney;

	@Value("${autoReturnMoneyKF:false}")
	private Boolean autoReturnMoneyKF;

	private static final String template = "<<<%s>>> \n 【服务名】: %s(%s) \n 【状态】: %s(%s) \n 【服务ip】: %s \n 【详情】: %s";


	/**
	 * 【退货退款】的售后单，超时7天未填写快递单号，订单将变回原状态
	 * 一小时执行一次
	 */
	@Scheduled(cron = "0 0 * * * ?")
	public void verifyInvalid() {
		log.info("===== 开始检查客户是否寄回快递 =====");
		// 获取等待寄回的退货信息列表
		List<ReturnInvalidResponse> pageList = returnGoodsDao.selectInvalidList();
		if (!CollectionUtils.isEmpty(pageList)) {
			for (ReturnInvalidResponse response : pageList) {
				returnGoodsOtherService.verifyInvalid(response);
			}
		}
		log.info("===== 结束检查客户是否寄回快递 =====");
	}

	/**
	 * 【仅退款】的售后单，修改审核状态
	 * 半小时执行一次
	 */
	@Scheduled(cron = "0 0/30 * * * ?")
	public void scanRefundOnly() {
		log.info("===== 开始检查【仅退款】的订单签收状态 =====");
		List<ReturnOrdersResponse> afterOnlyOrderInfos = returnGoodsDao.getAfterOnlyOrderInfos();
		List<Map<String, String>> requestData = afterOnlyOrderInfos.stream().map(e -> {
			Map<String, String> map = new HashMap<>();
			map.put("expressEno", e.getExpressNo());
			map.put("companyNo", e.getExpressCompany());
			return map;
		}).collect(Collectors.toList());
		if(CollectionUtils.isEmpty(requestData)){
			return;
		}
		String result = HttpClientUtil.doPostJson(supplyApiConfig.getUrl() + "/express/getLocalLogisticsInfo",
				JSON.toJSONString(requestData), supplyApiConfig.getHeadsMap());
		CommonResult commonResult = JSONObject.parseObject(result, CommonResult.class);
		if (null == commonResult || 200 != commonResult.getCode() || commonResult.getData() == null) {
			log.error("查询供应链物流接口异常====={}",commonResult.getMessage());
			return;
		}
		try {
			List<ExpressOrders> expressOrders = JSON.parseArray(JSON.toJSONString(commonResult.getData()), ExpressOrders.class);
			if(expressOrders.size() == 0){
				return;
			}
			Map<String, List<ExpressOrders>> expressOrdersMap = expressOrders.stream().collect(Collectors.groupingBy(e -> e.getCompanyNo() + e.getExpressEno()));
			for (ReturnOrdersResponse e : afterOnlyOrderInfos) {
				List<ExpressOrders> eos = expressOrdersMap.get(e.getExpressCompany() + e.getExpressNo());
				if (!CollectionUtils.isEmpty(eos)) {
					returnGoodsOtherService.verifyInvalidForOnlyRefund(e,eos.get(0));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		log.info("===== 结束检查【仅退款】的订单签收状态 =====");
	}

	/**
	 * 待退款同步到原路返回页
	 */
//	@Scheduled(cron = "0 0/10 0  * * ?")
	public void syncReturnRegister() {
		log.info("===== 开始同步原路返回页 =====");
		adminClient.syncReturnRegisterByRpc();
		log.info("===== 结束同步原路返回页 =====");
	}

	/**
	 * 待退款同步到原路返回页(客服标记的)
	 */
	@Scheduled(cron = "0 0/5 0  * * ?")
	public void syncReturnRegisterByMark() {
		log.info("===== 开始同步原路返回页(客服标记的) =====");
		adminClient.syncReturnRegisterByMark();
		log.info("===== 结束同步原路返回页(客服标记的) =====");
	}

	/**
	 * 售后类型为【退款】,查询用户申请售后时间已超24小时的供应商未审核的退货数据,
	 * 供应商审核状态改为审核通过,供应商处理时间now
	 */
	@Scheduled(cron = "0 0/5 * * * ?")
	public void verifyBankerStatus() {
		log.info("===== 开始检查售后类型为退款,供应商审核时间超24小时的供应商未审核的退货数据 =====");
		returnGoodsService.verifyBankerStatus();
		log.info("===== 结束检查售后类型为退款,供应商审核时间超24小时的供应商未审核的退货数据 =====");
	}

	/**
	 * 同步供应链供应商审核状态
	 */
	@Scheduled(cron = "0 0/3 * * * ?")
	public void checkSupplyChainReturnGoods(){
		log.info("===== 开始检查供应商审核状态修改 =====");
		returnGoodsService.checkSupplyChainReturnGoods();
		log.info("===== 结束检查供应商审核状态修改 =====");
	}


	/**
	 * 【补偿任务】订单状态异常修复：回到原状态和关闭状态
	 * 每天凌晨3点17分修复订单状态
	 */
	@Scheduled(cron = "0 17 3 * * ?")
	public void verifyReturnGoodsOrders(){
		log.info("===== 开始修复不正确的售后订单状态 =====");
		returnGoodsService.verifyReturnGoodsOrders(null);
		log.info("===== 结束修复不正确的售后订单状态 =====");
	}

	/**
	 * 客服审核后,数据库审核字段还是显示待审核
	 * 查询售后客服是否审核过
	 */
	@Scheduled(cron = "0 0/5 * * * ?")
	public void verifyReturnGoodsAudit(){
		log.info("===== 开始查询三天内申请的售后客服是否审核过 =====");
		returnGoodsService.verifyReturnGoodsAudit();
		log.info("===== 结束查询三天内申请的售后客服是否审核过 =====");
	}

	/**
	 * 10天内的原路返回页的退款单,120分钟执行一次,系统自动退款
	 */
	@Scheduled(cron = "0 0 9,12,15,17,19,21,23 * * ?")
	public void automaticRefund(){
		log.info("===== 开始查询10天内的原路返回页的退款单,系统自动退款 =====");
		if (autoReturnMoney){
			returnGoodsService.automaticRefund(10);
			log.info("===== 结束查询10天内的原路返回页的退款单,系统自动退款 =====");
		}
	}

	/**
	 * 客服标记自动退款订单
	 */
	@Scheduled(cron = "0 0 10,11,14,16,18,20,22 * * ?")
	public void orderReturnAuto(){
		log.info("===== 开始客服标记自动退款订单,系统自动退款 =====");
		if (autoReturnMoneyKF){
			returnGoodsService.orderReturnAuto();
			log.info("===== 结束客服标记自动退款订单,系统自动退款 =====");
		}
	}










	/*********************************** 以下是注释了的定时任务 *************************************/

	/**
	 * 退款后订单状态异常的订单
	 * (目前不需要供应商审核，只要签收就能同步到原路返回页)
	 */
//	@Scheduled(cron = "0 0/20 * * * ?")
	public void refundAfterOrderStatusError() {
		log.info("===退款后订单状态异常的订单===");
		try {
			List<String> orderIds = ordersService.refundAfterOrderStatusError();
			if (!CollectionUtils.isEmpty(orderIds)) {
				//存在实际支付成功，但是订单表状态为超时未支付的订单，发送预警
				String messageText = String
						.format(template, "退款成功后订单状态异常",
								"ygyx-quartz", "schedule",
								"500", "退款成功，订单状态异常",
								"",
								JSONObject.toJSONString("XXXX存在退款成功，但是订单状态异常数据：订单ID" + JSONArray.toJSONString(orderIds)));
				DingDingWebHookUtil.pushInfoToDingding(messageText);
			}
		} catch (Exception e) {
			log.error("===退款后订单状态异常的订单报错了==={}", e);
		}
	}

	/**
	 * 处理，已寄回供应商待审核的订单
	 */
//	@Scheduled(cron = "0 0 * * * ?")
	public void verifyBankerRece() {
		log.info("===== 开始检查供应商超24小时未审核已签收的订单情况 =====");
		returnGoodsService.verifyBankerRece();
		log.info("===== 结束检查供应商超24小时未审核已签收的订单情况 =====");
	}


	/**
	 * 检查售后类型为退款的订单 并把库存加回来
	 */
//	@Scheduled(cron = "0 0/5 * * * ?")
	public void verifyReturnRegister() {
		log.info("===== 开始检查售后类型为退款的订单 并把库存加回来 =====");
		returnGoodsService.verifyReturnRegister();
		log.info("===== 结束检查售后类型为退款的订单 并把库存加回来 =====");
	}

	//	@Scheduled(cron = "0 0/30 * * * ?")
	public void verifyReturnGoods() {
		log.info("===== 开始检查退货物流情况 =====");
		try {
			returnGoodsService.verifyLogistics();
		} catch (Throwable e) {
			log.error("===退货物流情况==={}", e);
		}
		log.info("===== 结束检查退货物流情况 =====");
	}

//	/**
//	 * 售后类型为退款,供应商拒绝或者供应商超24小时未审核后,
//	 * 检查客服审核状态,超24小时未审核则客服审核状态改为审核通过,
//	 * 客服处理时间now
//	 * 退货状态改为4.待退款
//	 */
//	@Scheduled(cron = "0 4 * * * ?")
//	public void verifyServiceStatus() {
//		log.info("===== 开始检查售后类型为退款,客服审核状态,超24小时未审核 =====");
//		returnGoodsService.verifyServiceStatus();
//		log.info("===== 结束检查售后类型为退款,客服审核状态,超24小时未审核 =====");
//	}

//	/**
//	 * 售后类型为仅退款,
//	 * 检查客服审核状态,超24小时未审核则客服审核状态改为审核通过,
//	 * 客服处理时间now
//	 * 退货状态改为4.待退款
//	 */
//	@Scheduled(cron = "0 6 * * * ?")
//	public void verifyServiceStatusByTwo() {
//		log.info("===== 开始检查售后类型为仅退款,客服审核状态,超24小时未审核 =====");
//		returnGoodsService.verifyServiceStatusByTwo();
//		log.info("===== 结束检查售后类型为仅退款,客服审核状态,超24小时未审核 =====");
//	}


}
